package ConnectivityEditor.Window;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import javax.media.opengl.GL2;
import javax.media.opengl.glu.GLU;
import javax.media.opengl.glu.GLUquadric;
import Builder.MainCamera;
import Common.Matrix4;
import Common.Ray3;
import Common.Vector3f;
import Connectivity.Connectivity;
import Connectivity.Stud;
import LDraw.Support.MatrixMath;
import LDraw.Support.type.LDrawGridTypeT;
public class StudRenderer extends DefaultConnectivityRenderer {
private Stud stud;
public StudRenderer(MainCamera camera, Connectivity conn) {
super(camera, conn);
stud = (Stud) conn;
}
private Vector3f[] getVertices() {
ArrayList<Vector3f> vertices = new ArrayList<Vector3f>();
Vector3f vertex;
for (int column = 0; column + 1 < stud.getheight(); column += 2) {
for (int row = 0; row + 1 < stud.getwidth(); row += 2) {
if (stud.getMatrixItem()[column + 1][row + 1].getAltitude() == 29)
continue;
if (stud.getMatrixItem()[column][row].getAltitude() != 29) {
vertex = new Vector3f(LDrawGridTypeT.Coarse.getXZValue()
* row / 2, 0, -LDrawGridTypeT.Coarse.getXZValue()
* column / 2);
vertices.add(vertex);
}
if (stud.getMatrixItem()[column + 2][row].getAltitude() != 29) {
vertex = new Vector3f(LDrawGridTypeT.Coarse.getXZValue()
* (row / 2), 0, -LDrawGridTypeT.Coarse.getXZValue()
* (column / 2 + 1));
vertices.add(vertex);
}
if (stud.getMatrixItem()[column + 2][row + 2].getAltitude() != 29) {
vertex = new Vector3f(LDrawGridTypeT.Coarse.getXZValue()
* (row / 2 + 1), 0,
-LDrawGridTypeT.Coarse.getXZValue()
* (column / 2 + 1));
vertices.add(vertex);
}
if (stud.getMatrixItem()[column][row + 2].getAltitude() != 29) {
vertex = new Vector3f(LDrawGridTypeT.Coarse.getXZValue()
* (row / 2 + 1), 0,
-LDrawGridTypeT.Coarse.getXZValue() * (column / 2));
vertices.add(vertex);
}
}
}
Vector3f[] retArray = new Vector3f[vertices.size()];
for (int i = 0; i < vertices.size(); i++) {
retArray[i] = stud.getTransformMatrix().transformPoint(
vertices.get(i));
}
return retArray;
}
@Override
public void draw(GL2 gl2) {
if (conn.isSelected())
gl2.glColor3f(0.2f, 0.2f, 0.2f);
else
gl2.glColor3f(1f, 0, 0);
// draw base
gl2.glLoadMatrixf(camera.getModelView(), 0);
gl2.glPointSize(10);
gl2.glBegin(GL2.GL_POINTS);
for (Vector3f vertex : getVertices())
gl2.glVertex3f(vertex.x, vertex.y, vertex.z);
gl2.glEnd();
gl2.glPointSize(1);
// Draw Stud Disk (possible styles: FILL, LINE, POINT).
gl2.glBegin(GL2.GL_QUADS); // draw using triangles
for (Vector3f vertex : getCylinderVertices())
gl2.glVertex3f(vertex.x, vertex.y, vertex.z);
gl2.glEnd();
gl2.glBegin(GL2.GL_TRIANGLES);
for (Vector3f vertex : getDiskVertices())
gl2.glVertex3f(vertex.x, vertex.y, vertex.z);
gl2.glEnd();
}
private Vector3f[] getDiskVertices() {
ArrayList<Vector3f> vertices = new ArrayList<Vector3f>();
final float diskRadius = LDrawGridTypeT.Medium.getXZValue() / 1.6f;
final float diskHeight = -LDrawGridTypeT.Fine.getYValue() * 2;
Vector3f vertex;
int slice = 24;
for (int column = 0; column < stud.getheight(); column += 2) {
for (int row = 0; row < stud.getwidth(); row += 2) {
if (stud.getMatrixItem()[column + 1][row + 1].getAltitude() == 29)
continue;
vertex = new Vector3f(LDrawGridTypeT.Coarse.getXZValue() / 2
+ LDrawGridTypeT.Coarse.getXZValue() * (row / 2),
diskHeight, -LDrawGridTypeT.Coarse.getXZValue() / 2
- LDrawGridTypeT.Coarse.getXZValue()
* (column / 2));
for (int sliceIndex = 0; sliceIndex < slice - 1; sliceIndex++) {
vertices.add(vertex);
vertices.add(vertex.add(
(float) (diskRadius * Math.cos((sliceIndex)
* Math.PI * 2 / (slice - 1))),
0,
(float) (diskRadius * Math.sin((sliceIndex)
* Math.PI * 2 / (slice - 1)))));
vertices.add(vertex.add(
(float) (diskRadius * Math.cos((sliceIndex + 1)
* Math.PI * 2 / (slice - 1))),
0,
(float) (diskRadius * Math.sin((sliceIndex + 1)
* Math.PI * 2 / (slice - 1)))));
}
}
}
Vector3f[] retArray = new Vector3f[vertices.size()];
for (int i = 0; i < vertices.size(); i++) {
retArray[i] = stud.getTransformMatrix().transformPoint(
vertices.get(i));
}
return retArray;
}
private Vector3f[] getCylinderVertices() {
ArrayList<Vector3f> vertices = new ArrayList<Vector3f>();
final float cylinderRadius = LDrawGridTypeT.Medium.getXZValue() / 1.6f;
final float cylinderHeight = -LDrawGridTypeT.Fine.getYValue() * 2;
Vector3f vertex;
int slice = 24;
for (int column = 0; column < stud.getheight(); column += 2) {
for (int row = 0; row < stud.getwidth(); row += 2) {
if (stud.getMatrixItem()[column + 1][row + 1].getAltitude() == 29)
continue;
vertex = new Vector3f(LDrawGridTypeT.Coarse.getXZValue() / 2
+ LDrawGridTypeT.Coarse.getXZValue() * (row / 2), 0,
-LDrawGridTypeT.Coarse.getXZValue() / 2
- LDrawGridTypeT.Coarse.getXZValue()
* (column / 2));
for (int sliceIndex = 0; sliceIndex < slice - 1; sliceIndex++) {
vertices.add(vertex.add(
(float) (cylinderRadius * Math.cos(sliceIndex
* Math.PI * 2 / (slice - 1))),
0,
(float) (cylinderRadius * Math.sin(sliceIndex
* Math.PI * 2 / (slice - 1)))));
vertices.add(vertex.add(
(float) (cylinderRadius * Math.cos((sliceIndex + 1)
* Math.PI * 2 / (slice - 1))),
0,
(float) (cylinderRadius * Math.sin((sliceIndex + 1)
* Math.PI * 2 / (slice - 1)))));
vertices.add(vertex.add(
(float) (cylinderRadius * Math.cos((sliceIndex + 1)
* Math.PI * 2 / (slice - 1))),
cylinderHeight,
(float) (cylinderRadius * Math.sin((sliceIndex + 1)
* Math.PI * 2 / (slice - 1)))));
vertices.add(vertex.add(
(float) (cylinderRadius * Math.cos(sliceIndex
* Math.PI * 2 / (slice - 1))),
cylinderHeight,
(float) (cylinderRadius * Math.sin(sliceIndex
* Math.PI * 2 / (slice - 1)))));
}
}
}
Vector3f[] retArray = new Vector3f[vertices.size()];
for (int i = 0; i < vertices.size(); i++) {
retArray[i] = stud.getTransformMatrix().transformPoint(
vertices.get(i));
}
return retArray;
}
@Override
public boolean isHitted(MainCamera camera, float screenX, float screenY,
FloatBuffer distance) {
Ray3 ray = camera.getRay(screenX, screenY);
FloatBuffer distanceTemp = FloatBuffer.allocate(1);
distanceTemp.put(Float.MAX_VALUE);
Vector3f[] vertices = getCylinderVertices();
boolean isHitted = false;
for (int i = 0; i < vertices.length; i += 4) {
if (MatrixMath.V3RayIntersectsTriangle(ray, vertices[i],
vertices[(i + 1)], vertices[(i + 2)], distanceTemp, null)) {
if (distance != null)
if (distanceTemp.get(0) < distance.get(0))
distance.put(0, distanceTemp.get(0));
isHitted = true;
}
if (MatrixMath.V3RayIntersectsTriangle(ray, vertices[i + 2],
vertices[(i + 3)], vertices[i], distanceTemp, null)) {
if (distance != null)
if (distanceTemp.get(0) < distance.get(0))
distance.put(0, distanceTemp.get(0));
isHitted = true;
}
}
vertices = getDiskVertices();
for (int i = 0; i < vertices.length; i += 3) {
if (MatrixMath.V3RayIntersectsTriangle(ray, vertices[i],
vertices[(i + 1)], vertices[(i + 2)], distanceTemp, null)) {
if (distance != null)
if (distanceTemp.get(0) < distance.get(0))
distance.put(0, distanceTemp.get(0));
isHitted = true;
}
}
lastHittedDistance = distance.get(0);
return isHitted;
}
}